#ifndef MASTERTASK
#define MASTERTASK

/*!
 * \file MasterTask.h
 * \author aimery aviles / thomas raynal
 * \version 2.0
 */

#include "AbstractGridSlaveTask.h"
#include "WorkTable.h"
#include "WorkerGraph.h"
#include "Utils.h"
#include "string"
#include <boost/shared_ptr.hpp>

/*! \namespace Network
 * 
 * Group master/slave task template & task handling utilities (trees & graphs)
 */
namespace MasterWorkerFramework
{
/*! \class AbstractGridSlaveTask
* \brief Represent a Master task (container & routines for handling collections of slave tasks) 
*/
class GridMasterTask {
	
	public:
	GridMasterTask()
	{
		tasks = new std::vector<AbstractGridSlaveTask*>();
		isConsolidated= false;
	}

	/*!
	*  \brief Are all the slave tasks completed?
	*
	*/
	bool IsDone()
	{
		bool result = true;
		for (std::vector<AbstractGridSlaveTask*>::iterator task = tasks->begin(); task != tasks->end(); task++)
		{
			if (!(*task)->GetStatut()==TASK_STATUT::COMPLETED)
			{
				return false;
				break;
			}
		}
		return result;
	}

	/*!
	*  \brief Add a task to proceeded
	*
	*/
	void AddTask(AbstractGridSlaveTask* task)
	{
		tasks->push_back(task);
	}

	/*!
	*  \brief Get the number of tasks loaded
	*
	*/
	int GetTaskCount()
	{
		return tasks->size();
	}

	/*!
	*  \brief Get the loaded tasks
	*
	*/
	std::vector<AbstractGridSlaveTask*>* GetTasks()
	{
		return tasks;
	}

	/*!
	*  \brief Get a task
	*
	*/
	AbstractGridSlaveTask* GetTask (std::string* hash_code)
	{
		for (std::vector<AbstractGridSlaveTask*>::iterator task = tasks->begin(); task != tasks->end(); task++)
		{
			if (*(*task)->GetHash()==*(hash_code))
			{
				return (*task);
			}
		}
	}

	/*!
	*  \brief Create the task trees. Resolve the dependancies.
	*
	*/
	void Build()
	{
		if (tasks->size()>0 && isConsolidated==false)
		{
				workerTrees = new WorkerGraph();
				workerTrees->Map__(*tasks);
				workTable = new WorkTable(workerTrees);
				isConsolidated = true;
		}
	}

	/*!
	*  \brief Get the task available for processing in the current context.
	*
	*/
	std::vector<AbstractGridSlaveTask*>* GetBach()
	{
		if (isConsolidated==false)
		{
			Build();
		}

			batch_ = workTable->GetBatch();
			return batch_;
	}

	~GridMasterTask()
	{
		if (NULL!=workerTrees)
			delete workerTrees;
		if (NULL!=workTable)
			delete workTable;
	}

	private:
	std::vector<AbstractGridSlaveTask*>* tasks;
	std::vector<AbstractGridSlaveTask*>* batch_;
	WorkerGraph* workerTrees;
	WorkTable* workTable;
	bool isConsolidated;
};
}
#endif